/*
 * FileName: cp1.c
 * Author  : mofei
 * History : 2014-07-22
 * Desc    : version 1 of cp - uses read and write tunable buffer size.
 *           usage: cp1 src dest
 */

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>

#define BUFFERSIZE 4096
#define COPYMODE   0644

int oops(char *, char *);

int main(int argc, char *argv[]) {
    int  in_fd, out_fd; //n_chars;
    char buf[BUFFERSIZE], file_name[256];
    ssize_t n_chars;
    DIR *dir_ptr;        /* the directory */

    /* check args */
    if(argc != 3) {
        fprintf(stderr, "usage: %s source destination\n", *argv);
        return -1;
    }

    /* open files */
    if((in_fd = open(argv[1], O_RDONLY)) == -1)
        oops("Cannot open ", argv[1]);

    /* create files */
    if((dir_ptr = opendir(argv[2])) == NULL) {
        if((out_fd = creat(argv[2], COPYMODE)) == -1)
            oops("Cannot create ", argv[2]);
        //else
            //fprintf(stderr,"cp1: cannot open %s\n", argv[2]);
    } else {
        strcat(file_name, argv[2]);
        strcat(file_name, argv[1]);
        //printf("my test 1 file_name=%s\n", file_name);
        if((out_fd = creat(file_name, COPYMODE)) == -1)
            oops("cannot create", file_name);
    }

    /* copy files */
    while((n_chars = read(in_fd, buf, BUFFERSIZE)) > 0) 
        if(write(out_fd, buf, n_chars) != n_chars) 
            oops("Write error to ", argv[2]);

    if(n_chars == -1)
        oops("Read error from ", argv[1]);

    /* close files */
    if(close(in_fd) == -1 || close(out_fd) == -1)
        oops("Error closing files ", "");

    return 0;
}

int oops(char *src, char *desc) {
    fprintf(stderr, "Error: %s ", src);
    perror(desc);

    return -1;
}

